﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Printing;
using System.Drawing.Imaging;
using System.Reflection;
using System.Diagnostics;

namespace PCR
{
    using PCR.Base;
    using PCR.Logic;

    public partial class FormReportPrinting : DevComponents.DotNetBar.Office2007Form
    {
        struct PrintingResultControls
        {
            public System.Windows.Forms.TextBox VirusResultText;
            public System.Windows.Forms.TextBox VirusReferenceText;

            public PrintingResultControls(System.Windows.Forms.TextBox virusResutText,
                System.Windows.Forms.TextBox virusReferenceText)
            {
                VirusResultText = virusResutText;
                VirusReferenceText = virusReferenceText;
            }
        }

        IPatientReport _patientReport;
        IDictionary<string, PrintingResultControls> _printingControls = new Dictionary<string, PrintingResultControls>();
        VirusTypeUI _virusTypeUI;
        
        public FormReportPrinting(IPatientReport patientReport)
        {
            InitializeComponent();
            System.Diagnostics.Debug.Assert(patientReport != null);
            this._patientReport = patientReport;
            
            this._virusTypeUI = new VirusTypeUI(this.panelPrinting, PCRRoot.Instance.VirusTypeManager.List);

            // Initialize the control container
            //string[] virusTypeNames = {"16", "18", "31", "33", "35", "39", "45", "51", 
            //                              "52", "53", "56", "58", "59", "66", "68"};

            //foreach(string virusTypeName in virusTypeNames)
            //{
            //    FieldInfo virusResultField = typeof(FormReportPrinting).GetField("textResultVirus" + virusTypeName);
            //    FieldInfo virusReferenceField = typeof(FormReportPrinting).GetField("textRefrenceVirus" + virusTypeName);

            //    System.Windows.Forms.TextBox textResult = virusResultField.GetValue(this) as System.Windows.Forms.TextBox;
            //    System.Diagnostics.Debug.Assert(textResult != null);
            //    System.Windows.Forms.TextBox textReference = virusReferenceField.GetValue(this) as System.Windows.Forms.TextBox;
            //    System.Diagnostics.Debug.Assert(textReference != null);
                
            //    PrintingResultControls printingControls = new PrintingResultControls(textResult, textReference);
            //    this._printingControls.Add(virusTypeName, printingControls);
            //}
        }

        private void FormReportPrinting_Load(object sender, EventArgs e)
        {
            IPrintingSetting printingSetting = PCRRoot.Instance.ConfigManager.PrintingSetting;
            System.Diagnostics.Debug.Assert(printingSetting != null);
            
            //////////////////////////////////////////////////////////////////////////
            // Set title
            this.textTitle.Text = printingSetting.Title;
            this.textTitle.BackColor = SystemColors.Window;
            this.textProjectName.Text = printingSetting.ProjectName;
            this.textCheckMethod.Text = PCRRoot.CheckMethodString(this._patientReport.CheckMethod);
            this.textReceiveTime.Text = GetPrintingDateString(this._patientReport.SampleReceiveDate);
            
            //////////////////////////////////////////////////////////////////////////
            // Set patient basic information
            this.textPatientName.Text = this._patientReport.Name;
            this.textPatientID.Text = "";
            this.textMedicalBranch.Text = printingSetting.MedicalBranch;
            this.textSampleID.Text = this._patientReport.SampleID;
            this.textGender.Text = PCRRoot.GenderString(this._patientReport.Gender);
            this.textBedNo.Text = printingSetting.BedNo;
            this.textSenderDoctor.Text = printingSetting.SenderDoctor;
            this.textReportTime.Text = GetPrintingDateString(this._patientReport.ReportDate);
            this.textAge.Text = this._patientReport.Age.ToString();
            this.textDiagnosis.Text = printingSetting.Diagnosis;
            this.textSampleType.Text = PCRRoot.SampleTypeString(this._patientReport.SampleType); ;
            this.textMemo.Text = printingSetting.Memo;
            
            //////////////////////////////////////////////////
            // Set signature
            this.textCheckerSignature.Text = printingSetting.CheckerSignature;
            this.textAuditorSignature.Text = printingSetting.AuditorSignature;

            //////////////////////////////////////////////////
            // Set note and question
            this.textNoteContents.Text = printingSetting.Note;
            this.labelQuestionNote.Text = printingSetting.Question;
            
            // Set virus type exponent
            this._virusTypeUI.SetPatientVirus(this._patientReport.PatientVirusList);
            
            // Set other note controls' position
            this.panelNotes.Location = new Point(0, this._virusTypeUI.MaxYPos);

            this.splitterItems.Size = new Size(this.splitterItems.Width,
                this._virusTypeUI.MaxYPos - this.splitterInfoAndCheckItems.Location.Y +
                this.splitterInfoAndCheckItems.Size.Height);

            // Set the printing's real height
            Size oldSize = this.panelPrinting.Size;
            this.panelPrinting.Size = new Size(oldSize.Width,
                this.panelNotes.Location.Y + this.panelNotes.Size.Height);

            // Set the printing buttons' real position
            this.panelButtons.Location = new Point(this.panelPrinting.Location.X,
                this.panelPrinting.Location.Y + this.panelPrinting.Size.Height);

            // Set the form's real height, need to add title's height
            this.Size = new Size(this.Size.Width,
                this.panelButtons.Location.Y + this.panelButtons.Size.Height + 25);
        }

        void FindAndFillResult(IPatientVirus patientVirus)
        {
            IVirusType virusType = PCRRoot.Instance.VirusTypeManager.GetByID(patientVirus.VirusTypeID);
            System.Diagnostics.Debug.Assert(virusType != null, string.Format(
                    "Virus type {0} not found", patientVirus.VirusTypeID));

            if (virusType == null) // Virus type not found
                return;
            
            string virusTypeName = virusType.Name;
            
            // Compare the name, may be not correct, the virus type name if not contains the virus number
            // we hard code here
            bool bFind = false;
            foreach(KeyValuePair<string, PrintingResultControls> virusTypeControls in this._printingControls)
            {
                //virusTypeControls.Value.VirusResultText.Text = "阴性";
                
                if (virusTypeName.Contains(virusTypeControls.Key))
                {
                    double exponent = patientVirus.Exponent;

                    // 0 stands for "阴性"， > 0 means "阳性"
                    string strRst = "";
                    if (PCRRoot.JudgeExponent(exponent,out strRst))
                    {
                        virusTypeControls.Value.VirusResultText.Text = strRst;
                        virusTypeControls.Value.VirusResultText.ForeColor = Color.Red;
                        virusTypeControls.Value.VirusReferenceText.Text = patientVirus.Exponent.ToString();
                        virusTypeControls.Value.VirusReferenceText.ForeColor = Color.Red;
                    }
                    else
                    {
                        virusTypeControls.Value.VirusResultText.Text = strRst;
                        virusTypeControls.Value.VirusReferenceText.Text = patientVirus.Exponent.ToString();
                    }
                    
                    bFind = true;
                    break;
                }
            }

            if (!bFind)
            {
                System.Diagnostics.Debug.Assert(false, string.Format(
                    "Virus type {0} not found in printing!", virusType.Name));
            }
        }

        string GetPrintingDateString(DateTime date)
        {
            return date.ToString("yyyy-MM-dd HH:mm");
        }

        private void btnPrint_Click(object sender, EventArgs e)
        {
            PrintDialog printDialog = new PrintDialog();
            printDialog.Document = this.printDocument;

            if (printDialog.ShowDialog() == DialogResult.OK)
            {
                this.printDocument.Print();
            }
        }

        private void btnPrintPreview_Click(object sender, EventArgs e)
        {
            PrintPreviewDialog printPreviewDialog = new PrintPreviewDialog();
            printPreviewDialog.Document = this.printDocument;
            printPreviewDialog.ShowDialog();
        }

        private void printDocument_PrintPage(object sender, PrintPageEventArgs e)
        {
            Graphics myGraphics = this.CreateGraphics();

            // Get the whole form bitmap
            Bitmap formBitmat = new Bitmap(this.Size.Width, this.Size.Height, myGraphics);
            Rectangle rect = new Rectangle();
            rect.Location = new Point(0, 0);
            rect.Size = this.Size;

            rect.Location = this.panelPrinting.Location;
            rect.Size = this.panelPrinting.Size;
            
            this.panelPrinting.DrawToBitmap(formBitmat, rect);
            
            // Draw to the print document
            e.Graphics.DrawImage(formBitmat, 0, 0);
        }

        private void btnQuit_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.OK;
        }

        private void btnSetup_Click(object sender, EventArgs e)
        {
            PageSetupDialog pageSetupDialog = new PageSetupDialog();
            pageSetupDialog.Document = printDocument;
            pageSetupDialog.ShowDialog();
        }
        
        private void btnPrintSetting_Click(object sender, EventArgs e)
        {
            PrintDialog printDialog = new PrintDialog();
            printDialog.Document = this.printDocument;

            printDialog.ShowDialog();
        }
    }
    
    public class VirusTypeUI
    {
        public VirusTypeUI(Panel parentPanel, IList<IVirusType> virusTypes)
        {
            Debug.Assert(parentPanel != null);
            this._parentPanel = parentPanel;
            
            // Sort the items and should add the virus type here
            SortedDictionary<string, IVirusType> highDangerVirusTypes =
                new SortedDictionary<string, IVirusType>();
            SortedDictionary<string, IVirusType> lowDangerVirusTypes =
                new SortedDictionary<string, IVirusType>();
            
            foreach(IVirusType virusType in virusTypes)
            {
                if (virusType.VirusDefineType == VirusDefineType.HIGHDANGER)
                    highDangerVirusTypes.Add(virusType.Name, virusType);
                else
                    lowDangerVirusTypes.Add(virusType.Name, virusType);
            }

            // Calculate all the line number
            int lineCount = virusTypes.Count;
            if (highDangerVirusTypes.Count > 0) lineCount++; // Add one line for high danger virus type title
            if (lowDangerVirusTypes.Count > 0) lineCount++; // Add one line for low danger virus type title

            Point startLeftPt = new Point(43, 220);
            Point startRightPt = new Point(400, 220);
            this._maxYPos = startLeftPt.Y;

            // Add high danger virus lines
            int currentLine = 0;
            Point itemStartPt = new Point();
            
            foreach(IVirusType virusType in highDangerVirusTypes.Values)
            {
                if (currentLine == 0) // Add high danger information
                {
                    //TextBox highDangerTextbox = new TextBox();
                    //highDangerTextbox.BackColor = System.Drawing.Color.White;
                    Label highDangerTextbox = new Label();
                    highDangerTextbox.BorderStyle = System.Windows.Forms.BorderStyle.None;
                    highDangerTextbox.Font = new System.Drawing.Font("宋体", 11.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
                    highDangerTextbox.ForeColor = System.Drawing.SystemColors.ControlText;
                    highDangerTextbox.Location = startLeftPt;
                    highDangerTextbox.Name = "textHighDanger";
                    //highDangerTextbox.ReadOnly = true;
                    highDangerTextbox.Size = new System.Drawing.Size(317, 18);
                    //highDangerTextbox.TabIndex = 7;
                    highDangerTextbox.Text = "=============高危型亚型=============";
                    //highDangerTextbox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
                    highDangerTextbox.Visible = true;
                    this._parentPanel.Controls.Add(highDangerTextbox);

                    currentLine++;
                }

                if (currentLine < lineCount/2)
                {
                    itemStartPt.X = startLeftPt.X;
                    itemStartPt.Y = startLeftPt.Y + currentLine * 18;
                }
                else
                {
                    itemStartPt.X = startRightPt.X;
                    itemStartPt.Y = startRightPt.Y + (currentLine - lineCount / 2) * 18;
                }

                this._maxYPos = Math.Max(this._maxYPos, itemStartPt.Y + 18);

                VirtusTypeUIItem item = new VirtusTypeUIItem(this._parentPanel, itemStartPt, virusType);
                this._virusTypeUIItems.Add(virusType.ObjectID.ToString(), item);
                currentLine++;
            }

            int lowLine = 0;
            // Add low danger virus lines
            foreach(IVirusType virusType in lowDangerVirusTypes.Values)
            {
                if (lowLine == 0) // Add high danger information
                {
                    if (currentLine < lineCount / 2)
                    {
                        itemStartPt.X = startLeftPt.X;
                        itemStartPt.Y = startLeftPt.Y + currentLine * 18;
                        this._maxYPos = itemStartPt.Y + 18;
                    }
                    else
                    {
                        itemStartPt.X = startRightPt.X;
                        itemStartPt.Y = startRightPt.Y + (currentLine - lineCount / 2) * 18;
                    }

                    this._maxYPos = Math.Max(this._maxYPos, itemStartPt.Y + 18);

                    //TextBox lowDangerTextbox = new TextBox();
                    Label lowDangerTextbox = new Label();
                    //lowDangerTextbox.BackColor = System.Drawing.Color.White;
                    lowDangerTextbox.BorderStyle = System.Windows.Forms.BorderStyle.None;
                    lowDangerTextbox.Font = new System.Drawing.Font("宋体", 11.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
                    lowDangerTextbox.ForeColor = System.Drawing.SystemColors.ControlText;
                    lowDangerTextbox.Location = itemStartPt;
                    lowDangerTextbox.Name = "textLowDanger";
                    //lowDangerTextbox.ReadOnly = true;
                    lowDangerTextbox.Size = new System.Drawing.Size(317, 18);
                    lowDangerTextbox.Text = "=============低危型亚型=============";
                    //lowDangerTextbox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
                    lowDangerTextbox.Visible = true;
                    this._parentPanel.Controls.Add(lowDangerTextbox);
                    
                    currentLine++;
                    lowLine++;
                }

                if (currentLine < lineCount / 2)
                {
                    itemStartPt.X = startLeftPt.X;
                    itemStartPt.Y = startLeftPt.Y + currentLine * 18;
                    this._maxYPos = itemStartPt.Y + 18;
                }
                else
                {
                    itemStartPt.X = startRightPt.X;
                    itemStartPt.Y = startRightPt.Y + (currentLine - lineCount / 2) * 18;
                }

                this._maxYPos = Math.Max(this._maxYPos, itemStartPt.Y + 18);
                
                //itemStartPt.X = startRightPt.X;
                //itemStartPt.Y = startRightPt.Y + currentLine * 18;
                //this._maxYPos = Math.Max(this._maxYPos, itemStartPt.Y + 18);
                
                VirtusTypeUIItem item = new VirtusTypeUIItem(this._parentPanel, itemStartPt, virusType);
                this._virusTypeUIItems.Add(virusType.ObjectID.ToString(), item);
                currentLine++;
            }
            
        }
        
        public void SetPatientVirus(IList<IPatientVirus> patientViruses)
        {
            Debug.Assert(patientViruses != null);

            foreach(IPatientVirus patientVirus in patientViruses)
            {
                IVirusType virusType = PCRRoot.Instance.VirusTypeManager.GetByID(patientVirus.VirusTypeID);
                if (virusType == null) // Virus type not found
                {
                    System.Diagnostics.Trace.WriteLine(string.Format(
                            "Virus type {0} not found", patientVirus.VirusTypeID));
                    
                    continue;
                }
                
                VirtusTypeUIItem item = null;
                if (!this._virusTypeUIItems.TryGetValue(virusType.ObjectID.ToString(), out item))
                {
                    System.Diagnostics.Debug.Assert(false, 
                        string.Format("Virus type not found, name : {0}, object ID : {1}",
                        virusType.Name, virusType.ObjectID));
                    continue;
                }

                item = this._virusTypeUIItems[virusType.ObjectID.ToString()];
                double exponent = patientVirus.Exponent;

                // 0 stands for "阴性"， > 0 means "阳性"
                string strRst = "";
                if (PCRRoot.JudgeExponent(exponent, out strRst))
                {
                    item.VirusResultTextBox.Text = strRst;
                    item.VirusResultTextBox.ForeColor = Color.Red;
                    item.VirusReferenceTextBox.Text = patientVirus.Exponent.ToString();
                    item.VirusReferenceTextBox.ForeColor = Color.Red;
                }
                else
                {
                    item.VirusResultTextBox.Text = strRst;
                    item.VirusReferenceTextBox.Text = patientVirus.Exponent.ToString();
                }
            }
        }
        
        public int MaxYPos
        {
            get { return this._maxYPos; }
        }

        protected Panel _parentPanel;
        IDictionary<string, VirtusTypeUIItem> _virusTypeUIItems = new Dictionary<string, VirtusTypeUIItem>();
        int _maxYPos;
    }

    public class VirtusTypeUIItem
    {
        public VirtusTypeUIItem(Panel parentPanel, Point startPt, IVirusType virusType)
        {
            Debug.Assert(parentPanel != null);
            Debug.Assert(virusType != null);

            // Create the name label 
            this._lableVirusName = new Label();
            this._lableVirusName.AutoSize = true;
            this._lableVirusName.Font = new System.Drawing.Font("宋体", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            this._lableVirusName.Location = startPt;
            this._lableVirusName.Name = string.Format("labelVirus{0}", virusType.Name);
            this._lableVirusName.Size = new System.Drawing.Size(55, 15);
            this._lableVirusName.Text = virusType.Name;
            
            // Create the result textbox
            this._textBoxVirusResult = new Label();
            //this._textBoxVirusResult.BackColor = System.Drawing.Color.White;
            this._textBoxVirusResult.BorderStyle = System.Windows.Forms.BorderStyle.None;
            this._textBoxVirusResult.Font = new System.Drawing.Font("宋体", 11.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            this._textBoxVirusResult.ForeColor = System.Drawing.SystemColors.ControlText;
            Point resusltPos = new Point(startPt.X, startPt.Y);
            resusltPos.X += 113;
            this._textBoxVirusResult.Location = resusltPos;
            this._textBoxVirusResult.Name = string.Format("textResultVirus{0}", virusType.Name);
            //this._textBoxVirusResult.ReadOnly = true;
            this._textBoxVirusResult.Size = new System.Drawing.Size(60, 18);
            // this._textBoxVirusResult.TabIndex = 7;
            this._textBoxVirusResult.Text = "阴性";
            //this._textBoxVirusResult.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;

            // Create the reference textbox
            this._textBoxVirusReference = new Label();
            //this._textBoxVirusReference.BackColor = System.Drawing.Color.White;
            this._textBoxVirusReference.BorderStyle = System.Windows.Forms.BorderStyle.None;
            this._textBoxVirusReference.Font = new System.Drawing.Font("宋体", 11.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            this._textBoxVirusReference.ForeColor = System.Drawing.SystemColors.ControlText;
            Point refrencePos = new Point(startPt.X, startPt.Y);
            refrencePos.X += 203;
            this._textBoxVirusReference.Location = refrencePos;
            this._textBoxVirusReference.Name = string.Format("textRefrenceVirus{0}", virusType.Name);
            //this._textBoxVirusReference.ReadOnly = true;
            this._textBoxVirusReference.Size = new System.Drawing.Size(100, 18);
            //this._textBoxVirusRefrence.TabIndex = 7;
            this._textBoxVirusReference.Text = "";
            //this._textBoxVirusReference.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;

            parentPanel.Controls.Add(this._lableVirusName);
            parentPanel.Controls.Add(this._textBoxVirusResult);
            parentPanel.Controls.Add(this._textBoxVirusReference);
        }

        public Label VirusResultTextBox 
        { 
            get { return this._textBoxVirusResult; } 
        }

        public Label VirusReferenceTextBox 
        { 
            get { return this._textBoxVirusReference; } 
        }

        private Label _lableVirusName;
        //private TextBox _textBoxVirusResult;
        //private TextBox _textBoxVirusReference;
        private Label _textBoxVirusResult;
        private Label _textBoxVirusReference;
    }
}
